package it.bambo.tankwars;

import it.bambo.tankwars.model.*;
import org.lwjgl.LWJGLException;
import org.lwjgl.input.Keyboard;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;
import org.lwjgl.opengl.GL11;

import java.awt.*;
import org.lwjgl.Sys;

/**
 * Andreas Baumgartner: andreas@bambo.it
 */
public class TankwarsLWJGL {

    private BattleField battleField;

    /**
     * time at last frame
     */
    long lastFrame;

    /**
     * frames per second
     */
    int fps;
    /**
     * last fps time
     */
    long lastFPS;

    public TankwarsLWJGL(String title) {
        battleField = new BattleField(new Rectangle(800, 600));
        battleField.getUnits().add(new Tank(battleField, Color.BLUE, ControlType.KEYBOARD, new Point(10, 10)));
//        battleField.getUnits().add(new Tank(Color.GREEN, 10, 60));
    }

    public void start() {
        try {
            Display.setDisplayMode(new DisplayMode(800, 600));
            Display.create();
        } catch (LWJGLException e) {
            e.printStackTrace();
            System.exit(0);
        }

        // init OpenGL here
        initOpenGL();
        getDelta(); // call once before loop to initialise lastFrame
        lastFPS = getTime(); // call before loop to initialise fps timer
        while (!Display.isCloseRequested()) {
            int delta = getDelta();
            //configures keyboard to allow repeating events while holding key down
            Keyboard.enableRepeatEvents(true);
            pollInput(delta);
            // render OpenGL here
            renderOpenGL();
            Display.update();
            Display.sync(60); //max 60fps
        }

        Display.destroy();
    }

    public void initOpenGL() {
        GL11.glMatrixMode(GL11.GL_PROJECTION);
        GL11.glLoadIdentity();
        GL11.glOrtho(0, Display.getWidth(), Display.getHeight(), 0, -1, 1);
        GL11.glMatrixMode(GL11.GL_MODELVIEW);
    }

    public void renderOpenGL() {
        GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);

        for (Unit unit : battleField.getUnits()) {

            // Clear The Screen And The Depth Buffer
            GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);

            // R,G,B,A Set The Color To Blue One Time Only
            GL11.glColor3f(0.5f, 0.5f, 1.0f);

            //get coordinates from unit
            int quadSize = 20;
            int x = unit.getRect().x;
            int y = unit.getRect().y;
            
            // draw unit
            GL11.glPushMatrix();
            GL11.glTranslatef(x, y, 0);
            GL11.glBegin(GL11.GL_QUADS);
            GL11.glVertex2f(x - quadSize, y - quadSize);
            GL11.glVertex2f(x + quadSize, y - quadSize);
            GL11.glVertex2f(x + quadSize, y + quadSize);
            GL11.glVertex2f(x - quadSize, y + quadSize);
            GL11.glEnd();
            GL11.glPopMatrix();
                }
        updateFPS();
    }

    public void pollInput(int delta) {

        while (Keyboard.next()) {
            for (Unit unit : battleField.getUnits()) {
                if (ControlType.KEYBOARD.equals(unit.getControlType())) {

                    if (Keyboard.getEventKey() == Keyboard.KEY_UP) {
                            unit.executeCommand(new Command(CommandType.DIRECTION, 0));
                    } else if (Keyboard.getEventKey() == Keyboard.KEY_RIGHT) {                   
                            unit.executeCommand(new Command(CommandType.DIRECTION, 90));
                    } else if (Keyboard.getEventKey() == Keyboard.KEY_DOWN) {                  
                            unit.executeCommand(new Command(CommandType.DIRECTION, 180));
                    } else if (Keyboard.isKeyDown(Keyboard.KEY_LEFT)) {
                            unit.executeCommand(new Command(CommandType.DIRECTION, 270));
                            
                            
                    } else if (Keyboard.KEY_SPACE == Keyboard.getEventKey()) {
                        unit.executeCommand(new Command(CommandType.FIRE));
                    } else if (Keyboard.KEY_W == Keyboard.getEventKey()) {
                        unit.executeCommand(new Command(CommandType.TOWER_CHANGE, 0));
                    } else if (Keyboard.KEY_D == Keyboard.getEventKey()) {
                        unit.executeCommand(new Command(CommandType.TOWER_CHANGE, 90));
                    } else if (Keyboard.KEY_S == Keyboard.getEventKey()) {
                        unit.executeCommand(new Command(CommandType.TOWER_CHANGE, 180));
                    } else if (Keyboard.KEY_A == Keyboard.getEventKey()) {
                        unit.executeCommand(new Command(CommandType.TOWER_CHANGE, 270));
                    }
                }
            }
        }
    }

    /**
     * Calculate how many milliseconds have passed since last frame.
     *
     * @return milliseconds passed since last frame
     */
    public int getDelta() {
        long time = getTime();
        int delta = (int) (time - lastFrame);
        lastFrame = time;

        return delta;
    }

    /**
     * Get the accurate system time
     *
     * @return The system time in milliseconds
     */
    public long getTime() {
        return (Sys.getTime() * 1000) / Sys.getTimerResolution();
    }

    /**
     * Calculate the FPS and set it in the title bar
     */
    public void updateFPS() {
        if (getTime() - lastFPS > 1000) {
            Display.setTitle("FPS: " + fps);
            fps = 0;
            lastFPS += 1000;
        }
        fps++;
    }

    public static void main(String[] args) {
        TankwarsLWJGL main = new TankwarsLWJGL("Tank Wars");
        main.start();
    }

}
